# -*- coding: utf-8 -*-
"""
日志清洗模块
负责清理和标准化日志数据
"""

import re
import json
from typing import Dict, Any, List, Optional
from common.logger import get_logger
from common.utils import clean_text, extract_ip_from_text, extract_url_from_text

logger = get_logger(__name__)


class LogCleaner:
    """日志清洗器"""
    
    def __init__(self):
        """初始化日志清洗器"""
        self.sensitive_patterns = [
            r'password["\']?\s*[:=]\s*["\']?[^"\s]+["\']?',  # 密码
            r'token["\']?\s*[:=]\s*["\']?[^"\s]+["\']?',    # 令牌
            r'key["\']?\s*[:=]\s*["\']?[^"\s]+["\']?',      # 密钥
            r'secret["\']?\s*[:=]\s*["\']?[^"\s]+["\']?',   # 密钥
            r'api_key["\']?\s*[:=]\s*["\']?[^"\s]+["\']?',  # API密钥
        ]
        
        # 编译正则表达式
        self.sensitive_regex = [re.compile(pattern, re.IGNORECASE) for pattern in self.sensitive_patterns]
        
        # 日志级别映射
        self.level_mapping = {
            'ERROR': ['error', 'err', 'exception', 'fatal', 'critical'],
            'WARN': ['warn', 'warning', 'warn'],
            'INFO': ['info', 'information'],
            'DEBUG': ['debug', 'trace']
        }
    
    def clean_log(self, log_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        清洗单条日志
        
        Args:
            log_data: 原始日志数据
            
        Returns:
            清洗后的日志数据
        """
        try:
            cleaned_log = log_data.copy()
            
            # 清洗消息内容
            if 'message' in cleaned_log:
                cleaned_log['message'] = self._clean_message(cleaned_log['message'])
            
            # 清洗原始数据
            if 'raw_data' in cleaned_log:
                cleaned_log['raw_data'] = self._clean_raw_data(cleaned_log['raw_data'])
            
            # 标准化日志级别
            if 'level' in cleaned_log:
                cleaned_log['level'] = self._normalize_level(cleaned_log['level'])
            
            # 提取IP地址
            if 'message' in cleaned_log:
                ips = extract_ip_from_text(cleaned_log['message'])
                if ips:
                    cleaned_log['extracted_ips'] = ips
            
            # 提取URL
            if 'message' in cleaned_log:
                urls = extract_url_from_text(cleaned_log['message'])
                if urls:
                    cleaned_log['extracted_urls'] = urls
            
            # 添加清洗标记
            cleaned_log['cleaned'] = True
            cleaned_log['clean_timestamp'] = self._get_current_timestamp()
            
            return cleaned_log
            
        except Exception as e:
            logger.error(f"清洗日志失败: {e}")
            return log_data
    
    def clean_logs(self, logs: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """
        批量清洗日志
        
        Args:
            logs: 日志列表
            
        Returns:
            清洗后的日志列表
        """
        cleaned_logs = []
        
        for log in logs:
            try:
                cleaned_log = self.clean_log(log)
                cleaned_logs.append(cleaned_log)
            except Exception as e:
                logger.error(f"清洗单条日志失败: {e}")
                # 保留原始日志
                cleaned_logs.append(log)
        
        return cleaned_logs
    
    def _clean_message(self, message: str) -> str:
        """
        清洗消息内容
        
        Args:
            message: 原始消息
            
        Returns:
            清洗后的消息
        """
        if not message:
            return ""
        
        # 基础清理
        message = clean_text(message)
        
        # 移除敏感信息
        message = self._remove_sensitive_info(message)
        
        # 移除多余的空白字符
        message = re.sub(r'\s+', ' ', message).strip()
        
        return message
    
    def _clean_raw_data(self, raw_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        清洗原始数据
        
        Args:
            raw_data: 原始数据字典
            
        Returns:
            清洗后的原始数据
        """
        if not isinstance(raw_data, dict):
            return raw_data
        
        cleaned_data = {}
        
        for key, value in raw_data.items():
            if isinstance(value, str):
                # 清洗字符串值
                cleaned_value = self._clean_message(value)
                cleaned_data[key] = cleaned_value
            elif isinstance(value, dict):
                # 递归清洗嵌套字典
                cleaned_data[key] = self._clean_raw_data(value)
            else:
                # 保持其他类型不变
                cleaned_data[key] = value
        
        return cleaned_data
    
    def _remove_sensitive_info(self, text: str) -> str:
        """
        移除敏感信息
        
        Args:
            text: 原始文本
            
        Returns:
            移除敏感信息后的文本
        """
        for regex in self.sensitive_regex:
            text = regex.sub(r'\1***', text)
        
        return text
    
    def _normalize_level(self, level: str) -> str:
        """
        标准化日志级别
        
        Args:
            level: 原始级别
            
        Returns:
            标准化后的级别
        """
        if not level:
            return "INFO"
        
        level_upper = level.upper()
        
        # 直接匹配
        if level_upper in self.level_mapping:
            return level_upper
        
        # 模糊匹配
        for standard_level, variants in self.level_mapping.items():
            if level_upper in variants:
                return standard_level
        
        # 默认返回INFO
        return "INFO"
    
    def _get_current_timestamp(self) -> float:
        """
        获取当前时间戳
        
        Returns:
            当前时间戳
        """
        import time
        return time.time()
    
    def add_sensitive_pattern(self, pattern: str) -> None:
        """
        添加敏感信息模式
        
        Args:
            pattern: 正则表达式模式
        """
        try:
            compiled_pattern = re.compile(pattern, re.IGNORECASE)
            self.sensitive_regex.append(compiled_pattern)
            logger.info(f"添加敏感信息模式: {pattern}")
        except Exception as e:
            logger.error(f"添加敏感信息模式失败: {e}")
    
    def remove_sensitive_pattern(self, pattern: str) -> bool:
        """
        移除敏感信息模式
        
        Args:
            pattern: 正则表达式模式
            
        Returns:
            是否成功移除
        """
        try:
            for i, regex in enumerate(self.sensitive_regex):
                if regex.pattern == pattern:
                    del self.sensitive_regex[i]
                    logger.info(f"移除敏感信息模式: {pattern}")
                    return True
            return False
        except Exception as e:
            logger.error(f"移除敏感信息模式失败: {e}")
            return False
    
    def get_cleaning_stats(self) -> Dict[str, Any]:
        """
        获取清洗统计信息
        
        Returns:
            清洗统计信息
        """
        return {
            'sensitive_patterns_count': len(self.sensitive_regex),
            'level_mapping_count': len(self.level_mapping),
            'sensitive_patterns': [regex.pattern for regex in self.sensitive_regex]
        } 